/**
 * Package: String
 *
 * Requires: Char
 */

#define STR_APPEND   0xffff

/// <summary>Gets the number of characters in the current string.</summary>
/// <param name="str">The string.</param>
/// <returns>The number of characters in this instance.</returns>
word String_Length $opc(0x59) (char str[]);

/// <summary>Determines whether two strings have the same value.</summary>
/// <param name="str1">The first string.</param>
/// <param name="str2">The second string.</param>
/// <returns>True if the value of str1[] is the same as the value of str2[]; otherwise, false.</returns>
byte String_Equals(char str1[], char str2[])
{
    word i; i = 0;

    while (str1[i] || str2[i])
    {
        if (str1[i] != str2[i])
            return 0;

        i++;
    }

    return 1;
}

/// <summary>Reports the index of the first occurrence of a string, or one or more characters, within this string.</summary>
/// <param name="str">The string to examine.</param>
/// <param name="search">The string to search for.</param>
/// <returns>The zero-based index position of value if that string is found, or -1 if it is not.</returns>
int String_IndexOf(char str[], char search[])
{
    return String_IndexOfFrom(str, search, 0);
}

/// <summary>Reports the index of the first occurrence of a string, or one or more characters, within this string. The search starts at a specified character position and examines a specified number of character positions.</summary>
/// <param name="str">The string to examine.</param>
/// <param name="search">The string to search for.</param>
/// <param name="startIndex">The search starting position.</param>
/// <returns>The zero-based index position of value if that string is found, or -1 if it is not.</returns>
int String_IndexOfFrom(char str[], char search[], word startIndex)
{
    word i, j;
    i = startIndex; j = 0;
    char c;

    while (str[i])
    {
        if (str[i] == search[0])
        {
            j = 1;

            do
            {
                c = search[j];
            } while (c && search[i + j++]);

            if (!c)
                return i;
        }

        i++;
    }

    return -1;
}

/// <summary>Returns a value indicating whether 'search' occurs within 'str'.</summary>
/// <param name="str">The string to examine.</param>
/// <param name="search">The string to search for.</param>
/// <returns>True if the source sequence contains an element that has the specified value; otherwise, false.</returns>
byte String_Contains(char str[], char search[])
{
    return String_IndexOf(str, search) >= 0;
}

/// <summary>Determines whether the beginning of a string matches a specified string.</summary>
/// <param name="str">The string to examine.</param>
/// <param name="search">The string to check for.</param>
/// <returns>True if search matches the beginning of this string; otherwise, false.</returns>
byte String_StartsWith(char str[], char search[])
{
    return String_IndexOf(str, search) == 0;
}

/// <summary>Determines whether the end of this string matches the specified string.</summary>
/// <param name="str">The string to examine.</param>
/// <param name="search">The string to check for.</param>
/// <returns>True if search matches the end of this instance; otherwise, false.</returns>
byte String_EndsWith(char str[], char search[])
{
    return String_LastIndexOf(str, search) == String_Length(str) - String_Length(search);
}

int String_LastIndexOf(char str[], char search[]) { return -1; // TODO }

/// <summary>Repeats 'ch' 'count' times.</summary>
/// <param name="destination">The output array.</param>
/// <param name="ch">The char to repeat.</param>
/// <param name="count">The number of times ch should be repeated.</param>
void String_RepeatChar(char destination[], char ch, word count)
{
    while (count--)
        destination[count] = ch;
}

/// <summary>Repeats 'ch' 'count' times.</summary>
/// <param name="destination">The output array.</param>
/// <param name="str">The string to repeat.</param>
/// <param name="count">The number of times str should be repeated.</param>
void String_Repeat(char destination[], char str[], word count)
{
    word i, length;
    length = String_Length(str);

    while (count--)
    {
        i = 0;

        while (str[i])
            destination[count * length + i++] = ch;
    }
}

/// <summary>Converts the value of 'str' to lowercase.</summary>
/// <param name="destination">The destination array.</param>
/// <param name="str">The string to convert.</param>
void String_ToLower(char destination[], char str[])
{
    word i; i = 0;

    while (str[i])
        destination[i] = Char_ToLowercase(str[i++]);
}

/// <summary>Converts the value of 'str' to uppercase.</summary>
/// <param name="destination">The destination array.</param>
/// <param name="str">The string to convert.</param>
void String_ToUpper(char destination[], char str[])
{
    word i; i = 0;

    while (str[i])
        destination[i] = Char_ToUppercase(str[i++]);
}